﻿using DAO.Common;
using AutomationView.Views;
using System;
using System.Collections.Generic;
using System.Windows.Forms;

namespace AutomationView
{
    public abstract class AddCustomerEngine: BaseEngine
    {
        protected AddCustomerEngine()
        {
            Errors = new List<string>();

            Entity = new CustomerDataEntity();

            Handlers.Add(ViewState.AddCustomer.Start, StartStrategy);
            Handlers.Add(ViewState.AddCustomer.Error, ErrorStrategy);

            States.Add(ViewState.AddCustomer.Start, new List<Operation> { Operations.Save, Operations.Cancel, Operations.Input });
            States.Add(ViewState.AddCustomer.Error, new List<Operation> { });
        }

        #region Const

        public class Operations 
        {
            public static readonly Operation Save = new Operation("Save");
            public static readonly Operation Cancel = new Operation("Cancel");
            public static readonly Operation Input = new Operation("Input");
        }
        #endregion

        #region Current state

        public bool Success { get; set; }

        public List<string> Errors { get; private set; }

        public CustomerDataEntity Entity { get; protected set; }

        #endregion

        protected abstract ViewState StartStrategy(Operation action);

        protected abstract ViewState ErrorStrategy(Operation action);
    }

    public class FormAddCustomerEngine : AddCustomerEngine
    {
        Form form;

        public override void Start()
        {
            base.Start();
            
            this.form = new AddCustomerEngineView();

            form.Find("btnSave").Click += (o, e) => Accept(Operations.Save);
            form.Find("btnCancel").Click += (o, e) => Accept(Operations.Cancel);
            SimpleFactory.GetObject<Helper.FormRenderer>().Show(form);  //***Shouldn't call show() directly
        }
        #region Implemented

        protected override ViewState StartStrategy(Operation op)
        {
            if (op == Operations.Save)
            {
                ReadEntity();

                if (String.IsNullOrEmpty(Entity.CompanyName)) Errors.Add("Company can't be null");
                if (String.IsNullOrEmpty(Entity.Name)) Errors.Add("Name can't be null");

                if (Errors.Count > 0)
                    return ViewState.AddCustomer.Error;
                else
                {
                    var dao = SimpleFactory.GetObject<DAO.ICustomerDao>();
                    dao.Save(Entity);
                    Success = true;
                    return ViewState.AddCustomer.End;
                }
            }
            else if (op.Name == Operations.Input.Name)
            {
                var value = op.Arguments[1];

                switch (op.Arguments[0] as string)
                {
                    case "Name": tbContactName.Text = value as string; break;
                    case "CompanyName": tbCompanyName.Text = value as string; break;
                    case "DateOfBirth": dtBirth.Value = (DateTime)value; break;
                    default:
                        break;
                }
            }
            else if (op == Operations.Cancel)
            {
                return ViewState.AddCustomer.End;
            }

            return ViewState.AddCustomer.Start;
        }

        protected override ViewState ErrorStrategy(Operation op)
        {
            SimpleFactory.GetObject<Helper.FormRenderer>().Show(String.Join("\r\n", Errors));   //no use MessageBox.Show directly
            Errors.Clear();

            return ViewState.AddCustomer.Start;
        }

        protected override void End()
        {
            form.Close();
        }
        #endregion

        #region Controls

        public Control tbContactName { get { return form.Find("contactNameTextBox"); } }
        public Control tbCompanyName { get { return form.Find("companyNameTextBox"); } }
        public DateTimePicker dtBirth { get { return form.Find("dateOfBirthDateTimePicker") as DateTimePicker; } }

        #endregion

        private void ReadEntity()
        {
            this.Entity.Name = tbContactName.Text;
            this.Entity.CompanyName = tbCompanyName.Text;
            this.Entity.DateOfBirth = dtBirth.Value;
        }
    }
}
